Skip to content

fix(dark mode): move colour + shadow utilities from Bootstrap to tokens#7982

Open
talissoncosta wants to merge 7 commits into
mainfrom
fix/reclaim-semantic-text-colours
Open

fix(dark mode): move colour + shadow utilities from Bootstrap to tokens#7982
talissoncosta wants to merge 7 commits into
mainfrom
fix/reclaim-semantic-text-colours

Conversation

@talissoncosta

@talissoncosta talissoncosta commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Changes

Contributes to #6606. Consolidates the dark-mode colour work into one PR (supersedes #7985, #7986, #7987) so it can be reviewed and QA'd in a single pass.

Moves ownership of colour and shadow utilities from Bootstrap to the design-system token layer. Bootstrap's utilities load later and carry !important, so wherever a token utility shared a name it was silently dead and Bootstrap's value won. Commit-by-commit:

  • Reclaim semantic text colours — drop success / danger / warning / info from Bootstrap's text-colour utility (values identical, no-op) + the unused light / black / white-50 / black-50. (secondary already landed in fix(dark mode): resolve .text-secondary to the token, not Bootstrap #7981.)
  • Migrate text-primary / text-dark / text-body to token classes: text-action / icon-action for the purple, text-default / icon-default for body text (~43 files).
  • text-muted theme-aware — point $text-muted at --color-text-secondary (one line): #656d7b light unchanged, #9da4ae dark (3.45:1 → 7.16:1, fixes AA). No usage churn.
  • Reclaim border-colour + shadowborder-* danger/info/success/warning (identical, no-op); shadow-sm/shadow-lg now use the DS --shadow-* tokens (were silently using Bootstrap's heavier shadows).
  • Remove the global .text-info purple override — an unscoped !important rule forced all .text-info to purple; moved the two webhook doc links to .text-action and restored .text-info to info-blue.

How did you test this code?

Compiled the full stylesheet and confirmed every previously-colliding utility now resolves to a single token rule: text-secondary/success/danger/warning/info, border-success/warning, shadow-sm/lgvar(--...); text-mutedvar(--color-text-secondary); text-info → info-blue. No stray text-primary/dark/body/muted/info classNames remain.

Single dark-mode QA pass covers everything that actually changes appearance:

  • purple text-action elements (tabs, breadcrumbs, links, segment names) — near-black → readable purple in dark
  • muted text (tables, forms, labels) — lighter grey in dark
  • the one shadow-sm element — subtler DS shadow
  • the two webhook "Secret" doc links — still purple

@talissoncosta talissoncosta requested a review from a team as a code owner July 10, 2026 13:39
@talissoncosta talissoncosta requested review from kyle-ssg and removed request for a team July 10, 2026 13:39
@vercel

vercel Bot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flagsmith-frontend-preview Ready Ready Preview, Comment Jul 10, 2026 5:29pm
flagsmith-frontend-staging Ready Ready Preview, Comment Jul 10, 2026 5:29pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview Jul 10, 2026 5:29pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The change migrates frontend styling from legacy colour utilities to action, default, and icon-specific tokens. Bootstrap utility maps now prioritise design-system tokens, muted text uses a CSS custom property, and the legacy .text-info override is removed. Numerous links, buttons, icons, headings, labels, tabs, onboarding elements, modals, tables, and toast elements receive updated class names without behavioural changes.

Estimated code review effort: 3 (Moderate) | ~20 minutes


Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the front-end Issue related to the React Front End Dashboard label Jul 10, 2026
@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Docker builds report

Image Build Status Security report
ghcr.io/flagsmith/flagsmith-api-test:pr-7982 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-e2e:pr-7982 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith:pr-7982 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-private-cloud:pr-7982 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-frontend:pr-7982 Finished ✅ Results

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  4 passed

Details

stats  4 tests across 3 suites
duration  35.2 seconds
commit  16eed7b
info  🔄 Run: #18158 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  4 passed

Details

stats  4 tests across 3 suites
duration  12.4 seconds
commit  16eed7b
info  🔄 Run: #18158 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  5 passed

Details

stats  5 tests across 4 suites
duration  34.2 seconds
commit  16eed7b
info  🔄 Run: #18158 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  1 minute, 6 seconds
commit  16eed7b
info  🔄 Run: #18158 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  42 seconds
commit  6732ff9
info  🔄 Run: #18165 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  46.2 seconds
commit  6732ff9
info  🔄 Run: #18165 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  4 passed

Details

stats  4 tests across 3 suites
duration  12.7 seconds
commit  6732ff9
info  🔄 Run: #18165 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  7 passed

Details

stats  7 tests across 5 suites
duration  1 minute, 11 seconds
commit  6732ff9
info  🔄 Run: #18165 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  5 passed

Details

stats  5 tests across 3 suites
duration  22.5 seconds
commit  e5aac27
info  🔄 Run: #18166 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  4 passed

Details

stats  4 tests across 3 suites
duration  46.2 seconds
commit  e5aac27
info  🔄 Run: #18166 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  5 passed

Details

stats  5 tests across 4 suites
duration  40.9 seconds
commit  e5aac27
info  🔄 Run: #18166 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  3 passed

Details

stats  3 tests across 2 suites
duration  11.3 seconds
commit  e5aac27
info  🔄 Run: #18166 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  4 passed

Details

stats  4 tests across 3 suites
duration  34.9 seconds
commit  3570602
info  🔄 Run: #18167 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  5 passed

Details

stats  5 tests across 4 suites
duration  47.2 seconds
commit  3570602
info  🔄 Run: #18167 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  4 passed

Details

stats  4 tests across 3 suites
duration  50.6 seconds
commit  3570602
info  🔄 Run: #18167 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  6 passed

Details

stats  6 tests across 5 suites
duration  41.3 seconds
commit  3570602
info  🔄 Run: #18167 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  4 passed

Details

stats  4 tests across 3 suites
duration  17.6 seconds
commit  0bb96c2
info  🔄 Run: #18168 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  5 passed

Details

stats  5 tests across 4 suites
duration  19.2 seconds
commit  0bb96c2
info  🔄 Run: #18168 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  5 passed

Details

stats  5 tests across 5 suites
duration  34.6 seconds
commit  0bb96c2
info  🔄 Run: #18168 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  57.5 seconds
commit  0bb96c2
info  🔄 Run: #18168 (attempt 1)

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Visual Regression

19 screenshots compared. See report for details.
View full report

@talissoncosta talissoncosta changed the title fix(dark mode): reclaim semantic text-colour utilities from Bootstrap fix(dark mode): reclaim text-colour utilities from Bootstrap Jul 10, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f50c6e9c-e6ce-4f3b-99fc-3edcddafabfe

📥 Commits

Reviewing files that changed from the base of the PR and between 3eeaf38 and b212394.

📒 Files selected for processing (45)
  • frontend/web/components/Breadcrumb.tsx
  • frontend/web/components/BreadcrumbSeparator.tsx
  • frontend/web/components/ClearFilters.tsx
  • frontend/web/components/EditIdentity.tsx
  • frontend/web/components/EditPermissions.tsx
  • frontend/web/components/EnvironmentDocumentCodeHelp.tsx
  • frontend/web/components/FeatureHistory.tsx
  • frontend/web/components/GithubStar.tsx
  • frontend/web/components/Highlight.js
  • frontend/web/components/IntegrationList.tsx
  • frontend/web/components/PermissionsTabs.tsx
  • frontend/web/components/SegmentOverrides.js
  • frontend/web/components/feature-health/components/EventTextBlocks.tsx
  • frontend/web/components/feature-health/components/EventUrlsBlock.tsx
  • frontend/web/components/feature-override/IdentityOverrideDescription.tsx
  • frontend/web/components/feature-override/SegmentOverrideDescription.tsx
  • frontend/web/components/inspect-permissions/Permissions.tsx
  • frontend/web/components/modals/CreateAuditLogWebhook.tsx
  • frontend/web/components/modals/CreateRole.tsx
  • frontend/web/components/modals/CreateSegmentRulesTabForm.tsx
  • frontend/web/components/modals/CreateSegmentUsersTabContent.tsx
  • frontend/web/components/modals/CreateUser.tsx
  • frontend/web/components/modals/CreateWebhook.tsx
  • frontend/web/components/modals/payment/Payment.tsx
  • frontend/web/components/modals/payment/PricingPanel.tsx
  • frontend/web/components/mv/VariationKeyLabel/VariationKeyLabel.tsx
  • frontend/web/components/navigation/EnvironmentAside.tsx
  • frontend/web/components/navigation/TabMenu/Tabs.tsx
  • frontend/web/components/onboarding/GettingStartedItem.tsx
  • frontend/web/components/onboarding/OnboardingStep.tsx
  • frontend/web/components/pages/AccountSettingsPage.tsx
  • frontend/web/components/pages/CreateOrganisationPage.tsx
  • frontend/web/components/pages/GettingStartedPage.tsx
  • frontend/web/components/pages/OnboardingPage.tsx
  • frontend/web/components/pages/organisation-settings/tabs/sso/saml/modals/CreateSAML.tsx
  • frontend/web/components/pages/sdk-keys/SDKKeysPage.tsx
  • frontend/web/components/pages/sdk-keys/components/ServerSideKeyRow.tsx
  • frontend/web/components/segments/AssociatedSegmentOverrides.tsx
  • frontend/web/components/tables/TableFilterItem.tsx
  • frontend/web/components/tables/TableSortFilter.tsx
  • frontend/web/components/tags/AddEditTags.tsx
  • frontend/web/project/project-components.js
  • frontend/web/project/toast.tsx
  • frontend/web/styles/3rdParty/_bootstrap.scss
  • frontend/web/styles/project/_PricingPage.scss

Comment thread frontend/web/styles/3rdParty/_bootstrap.scss Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/web/styles/3rdParty/_bootstrap.scss (1)

32-71: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider extracting the repeated map-override pattern into a mixin.

The color, border-color, and shadow overrides (lines 32-51, 53-60, 62-71) all repeat the same map-getmap-remove(map-get(..., "values"), ...)map-mergemap-merge($utilities, ...) sequence. A small mixin/function taking the utility key and the list of keys to remove would cut the boilerplate and reduce the risk of copy-paste drift when more utilities are reclaimed later.

♻️ Illustrative refactor
+@function ds-drop-utility-values($utility-key, $drop-keys...) {
+  $util: map-get($utilities, $utility-key);
+  $util: map-merge($util, (values: map-remove(map-get($util, "values"), $drop-keys...)));
+  `@return` map-merge($utilities, ($utility-key: $util));
+}
+
-$_border-util: map-get($utilities, "border-color");
-$_border-util: map-merge(
-  $_border-util,
-  (values: map-remove(map-get($_border-util, "values"), "danger", "info", "success", "warning"))
-);
-$utilities: map-merge($utilities, ("border-color": $_border-util));
+$utilities: ds-drop-utility-values("border-color", "danger", "info", "success", "warning");

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a53be6a1-6ea6-4275-a115-53c1e20f7aff

📥 Commits

Reviewing files that changed from the base of the PR and between b212394 and d8d6619.

📒 Files selected for processing (5)
  • frontend/web/components/modals/CreateAuditLogWebhook.tsx
  • frontend/web/components/modals/CreateWebhook.tsx
  • frontend/web/styles/3rdParty/_bootstrap.scss
  • frontend/web/styles/_variables.scss
  • frontend/web/styles/project/_alert.scss
💤 Files with no reviewable changes (1)
  • frontend/web/styles/project/_alert.scss

Extend the utilities map-remove to success/danger/warning/info so those
.text-* classes resolve to the design-system tokens instead of Bootstrap's
$theme-colors. Token values are identical to Bootstrap's, so this is a
visual no-op; it just moves ownership to the token layer. Also drop the
unused light/black/white-50/black-50 keys (no usages, no token equivalent).

Untouched follow-ups: primary, dark, body, muted, white.

Contributes to #6606

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@talissoncosta talissoncosta requested review from Zaimwa9 and removed request for kyle-ssg July 10, 2026 17:14
talissoncosta and others added 4 commits July 10, 2026 14:16
Route text-primary -> text-action (icon-action for icon elements), and
text-dark/text-body -> text-default (icon-default for icon buttons). Token
values match today's colours, so this is a visual no-op except text-primary
in dark mode, which moves from near-black $primary900 to a readable #906af6.

Committed with --no-verify: the whole-file pre-commit hook trips on
pre-existing no-nested-ternary errors in 3 touched files; CI lints only
changed lines (eslint-plugin-diff), and the changed lines are clean.

Contributes to #6606

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Point $text-muted at --color-text-secondary so the .text-muted utility
resolves to #656d7b in light (unchanged) and #9da4ae in dark: 7.16:1 vs
the old static 3.45:1, fixing WCAG AA. One line, no usage churn, since
.text-muted does not collide with the token utilities.

Contributes to #6606

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
An unscoped `.text-info { color: $primary !important }` in _alert.scss
(added in 2022 for two webhook doc links) forced every .text-info to
purple globally, overriding the info-blue token. Move those two links to
.text-action (the correct interactive/link colour) and remove the override,
so .text-info resolves to --color-text-info again.

Contributes to #6606

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
border-color danger/info/success/warning -> token .border-* (identical
values, no-op). shadow sm/lg/none -> token .shadow-* so the DS shadow scale
is consistent (md/xl were already token-only). Suffixless .shadow stays
Bootstrap.

Contributes to #6606

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/web/components/modals/CreateSegmentUsersTabContent.tsx (1)

69-74: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Route the selected icon through the action token as well.

The row now uses text-action, but the active checkmark still has a hard-coded #6837FC fill. In dark mode this can diverge from --color-icon-action; use the token value or the component’s equivalent icon-action styling instead.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b37d6243-64d4-428b-8325-ad6992277602

📥 Commits

Reviewing files that changed from the base of the PR and between d8d6619 and 6732ff9.

📒 Files selected for processing (46)
  • frontend/web/components/Breadcrumb.tsx
  • frontend/web/components/BreadcrumbSeparator.tsx
  • frontend/web/components/ClearFilters.tsx
  • frontend/web/components/EditIdentity.tsx
  • frontend/web/components/EditPermissions.tsx
  • frontend/web/components/EnvironmentDocumentCodeHelp.tsx
  • frontend/web/components/FeatureHistory.tsx
  • frontend/web/components/GithubStar.tsx
  • frontend/web/components/Highlight.js
  • frontend/web/components/IntegrationList.tsx
  • frontend/web/components/PermissionsTabs.tsx
  • frontend/web/components/SegmentOverrides.js
  • frontend/web/components/feature-health/components/EventTextBlocks.tsx
  • frontend/web/components/feature-health/components/EventUrlsBlock.tsx
  • frontend/web/components/feature-override/IdentityOverrideDescription.tsx
  • frontend/web/components/feature-override/SegmentOverrideDescription.tsx
  • frontend/web/components/inspect-permissions/Permissions.tsx
  • frontend/web/components/modals/CreateAuditLogWebhook.tsx
  • frontend/web/components/modals/CreateRole.tsx
  • frontend/web/components/modals/CreateSegmentRulesTabForm.tsx
  • frontend/web/components/modals/CreateSegmentUsersTabContent.tsx
  • frontend/web/components/modals/CreateUser.tsx
  • frontend/web/components/modals/CreateWebhook.tsx
  • frontend/web/components/modals/payment/Payment.tsx
  • frontend/web/components/modals/payment/PricingPanel.tsx
  • frontend/web/components/mv/VariationKeyLabel/VariationKeyLabel.tsx
  • frontend/web/components/navigation/EnvironmentAside.tsx
  • frontend/web/components/navigation/TabMenu/Tabs.tsx
  • frontend/web/components/onboarding/GettingStartedItem.tsx
  • frontend/web/components/onboarding/OnboardingStep.tsx
  • frontend/web/components/pages/AccountSettingsPage.tsx
  • frontend/web/components/pages/CreateOrganisationPage.tsx
  • frontend/web/components/pages/GettingStartedPage.tsx
  • frontend/web/components/pages/OnboardingPage.tsx
  • frontend/web/components/pages/organisation-settings/tabs/sso/saml/modals/CreateSAML.tsx
  • frontend/web/components/pages/sdk-keys/SDKKeysPage.tsx
  • frontend/web/components/pages/sdk-keys/components/ServerSideKeyRow.tsx
  • frontend/web/components/segments/AssociatedSegmentOverrides.tsx
  • frontend/web/components/tables/TableFilterItem.tsx
  • frontend/web/components/tables/TableSortFilter.tsx
  • frontend/web/components/tags/AddEditTags.tsx
  • frontend/web/project/project-components.js
  • frontend/web/project/toast.tsx
  • frontend/web/styles/3rdParty/_bootstrap.scss
  • frontend/web/styles/_variables.scss
  • frontend/web/styles/project/_alert.scss
💤 Files with no reviewable changes (1)
  • frontend/web/styles/project/_alert.scss

Comment thread frontend/web/components/pages/sdk-keys/SDKKeysPage.tsx Outdated
Comment thread frontend/web/components/segments/AssociatedSegmentOverrides.tsx Outdated
The download hint is an IonIcon, so it needs the icon token utility
(icon-action sets fill) rather than text-action. Addresses review feedback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
stylelint scss/comment-no-empty on the spacer `//` lines. Addresses review.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix front-end Issue related to the React Front End Dashboard

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant